package com.zer0.tga.level;


import java.util.ArrayList;
import java.util.List;

import com.zer0.tga.art.Screen;
import com.zer0.tga.entity.Entity;
import com.zer0.tga.level.Room.RoomType;
import com.zer0.tga.math.BoundingBox;
import com.zer0.tga.math.Coordinate;
import com.zer0.tga.math.RandNum;


public class Level {


	public Room[][] rooms;

	public int currentRoom_x;
	public int currentRoom_y;

	private static final int LEVEL_X = 10;
	private static final int LEVEL_Y = LEVEL_X;

	private static final int SCREEN_CHANGE_RATE = 15;
	
	private static int goingToNorth = 0;
	private static int goingToSouth = 0;
	private static int goingToEast = 0;
	private static int goingToWest = 0;
	
	private static Screen oldRoom;
	private static Screen newRoom;
	
	
	public Level()
	{
		rooms = new Room[LEVEL_X][LEVEL_Y];
	}

	public Level(int roomCount)
	{
		this();
		createLevel(roomCount);
	}
	
    public void addEntityToCurrentRoom(Entity e) {
        e.init(this);

        rooms[currentRoom_x][currentRoom_y].addEntity(e);
    }

/*    public void removeEntity(Entity e) {
        e.removed = true;
    }*/


	
	public void tick()
	{
		rooms[currentRoom_x][currentRoom_y].tick();
	}

	public List<BoundingBox> getBoundingBox(Entity entity) {
		// TODO Auto-generated method stub
		return null;
	}
	
	public void createTestLevel()
	{
		 int x = 1, y = 1;
		 rooms[x][y]= new Room(this, RoomType.START_ROOM);
		 
		/* rooms[x][y].setEastDoor(true);
		 rooms[x][y].setWestDoor(true);
		 rooms[x][y].setNorthDoor(true);
		 rooms[x][y].setSouthDoor(true);*/
		 
		 currentRoom_x = x;
		 currentRoom_x = y; 
		 
	}

	
	
	public void createLevel(int maxRoomCount)
	{

		int currentRoomCount = 0;
		
		// create the first starting room

		int x = RandNum.getRandNum(0, LEVEL_X);
		int y = RandNum.getRandNum(0, LEVEL_Y);
		
		rooms[x][y] = new Room(this, RoomType.START_ROOM);
		currentRoom_x = x;
		currentRoom_y = y;
		
		
		ArrayList<Coordinate> currentRoomPositions = new ArrayList<Coordinate>();
		
		currentRoomPositions.add(new Coordinate(x,y));
		currentRoomCount++;
		/*
		// we don't want to add out of bound room positions
		if(x>1)
			availableRoomPositions.add(new Coordinate(x-1,y));
		if(x<ROOM_X-1)
			availableRoomPositions.add(new Coordinate(x+1,y));
		if(y>1)
			availableRoomPositions.add(new Coordinate(x,y-1));
		if(y<ROOM_Y-1)
			availableRoomPositions.add(new Coordinate(x,y+1));*/
		
		while(currentRoomCount<maxRoomCount)
		{
			// get a random room from list
			Coordinate roomCoord = currentRoomPositions.get(RandNum.getRandNum(0, currentRoomPositions.size()));
			
			// choose a random side and add a neighboor room to that room
			int side = RandNum.getRandNum(1,4);
			
			if(side == 1) //north
			{
				if(roomCoord.y!=0) // we cant add any more rooms this side 
				{
					Coordinate newRoomCoord = roomCoord.getNorthCoordinate();
					if(newRoomCoord != null && rooms[newRoomCoord.x][newRoomCoord.y] == null) //we cant add if there is a room here 
					{
						rooms[newRoomCoord.x][newRoomCoord.y] = new Room(this);
						currentRoomPositions.add(new Coordinate (newRoomCoord.x,newRoomCoord.y));
						currentRoomCount++;
						
						// add the rooms connection
						rooms[newRoomCoord.x][newRoomCoord.y].setSouthDoor(true);
						rooms[roomCoord.x][roomCoord.y].setNorthDoor(true);
						
					}
				}			 
			}
			else if(side == 2) //south
			{
				if(roomCoord.y!=LEVEL_Y-1) // we cant add any more rooms this side
				{
					Coordinate newRoomCoord = roomCoord.getSouthCoordinate();
					if(newRoomCoord != null  && rooms[newRoomCoord.x][newRoomCoord.y] == null) //we cant add if there is a room here 
					{
						rooms[newRoomCoord.x][newRoomCoord.y] = new Room(this);
						currentRoomPositions.add(new Coordinate (newRoomCoord.x,newRoomCoord.y));
						currentRoomCount++;
						
						// add the rooms connection
						rooms[newRoomCoord.x][newRoomCoord.y].setNorthDoor(true);
						rooms[roomCoord.x][roomCoord.y].setSouthDoor(true);
					}
				}	
				
			}
			else if(side == 3) //west
			{
				if(roomCoord.x!=0) // we cant add any more rooms this side
				{
					Coordinate newRoomCoord = roomCoord.getWestCoordinate();
					if(newRoomCoord != null && rooms[newRoomCoord.x][newRoomCoord.y] == null) //we cant add if there is a room here 
					{
						rooms[newRoomCoord.x][newRoomCoord.y] = new Room(this);
						currentRoomPositions.add(new Coordinate (newRoomCoord.x,newRoomCoord.y));
						currentRoomCount++;
						
						// add the rooms connection
						rooms[newRoomCoord.x][newRoomCoord.y].setEastDoor(true);
						rooms[roomCoord.x][roomCoord.y].setWestDoor(true);
					}
				}	
			}
			else if(side == 4) //east
			{
				if(roomCoord.x!=LEVEL_X-1) // we cant add any more rooms this side and  we cant add if there is a room here
				{
					Coordinate newRoomCoord = roomCoord.getEastCoordinate();
					if(newRoomCoord != null && rooms[newRoomCoord.x][newRoomCoord.y] == null) //we cant add if there is a room here 
					{
						rooms[newRoomCoord.x][newRoomCoord.y] = new Room(this);
						currentRoomPositions.add(new Coordinate (newRoomCoord.x,newRoomCoord.y));
						currentRoomCount++;
						
						// add the rooms connection
						rooms[newRoomCoord.x][newRoomCoord.y].setWestDoor(true);
						rooms[roomCoord.x][roomCoord.y].setEastDoor(true);
					}
				}	
			}
			
			//rooms[newRoom.x][newRoom.y] = new Room(RoomType.NORMAL_ROOM)				
		}
		
		//now we have to make a random room shop_room and the farthest room(?) BOSS room
		

	}

	public boolean hasNorthRoom()
	{
		return hasNorthRoom(new Coordinate(currentRoom_x,currentRoom_y));
	}
	
	public boolean hasSouthRoom()
	{
		return hasSouthRoom(new Coordinate(currentRoom_x,currentRoom_y));
	}
	
	public boolean hasWestRoom()
	{
		return hasWestRoom(new Coordinate(currentRoom_x,currentRoom_y));
	}
	
	public boolean hasEastRoom()
	{
		return hasEastRoom(new Coordinate(currentRoom_x,currentRoom_y));
	}
	
	
	public boolean hasNorthRoom(Coordinate room)
	{

		try {
			if((rooms[room.x][room.y-1] != null) && (rooms[room.x][room.y].hasNorthDoor))
				return true;
			else
				return false;
		} catch (ArrayIndexOutOfBoundsException e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
			return false;
		}
	}



	public boolean hasSouthRoom(Coordinate room)
	{
		try
		{
			if((rooms[room.x][room.y+1] != null) && (rooms[room.x][room.y].hasSouthDoor))
				return true;
			else
				return false;
		} catch (ArrayIndexOutOfBoundsException e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
			return false;
		}
	}


	public boolean hasWestRoom(Coordinate room)
	{
		try
		{
			if((rooms[room.x-1][room.y] != null) && (rooms[room.x][room.y].hasWestDoor))
				return true;
			else
				return false;
		} catch (ArrayIndexOutOfBoundsException e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
			return false;
		}
	}

	

	public boolean hasEastRoom(Coordinate room)
	{
		try
		{
			if((rooms[room.x+1][room.y] != null) && (rooms[room.x][room.y].hasEastDoor))
				return true;
			else
				return false;

		} catch (ArrayIndexOutOfBoundsException e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
			return false;
		}
	}
	
	public void goNorthRoom(Screen screen)
	{
		initChangeRoomScreens(screen);
		rooms[currentRoom_x][currentRoom_y].render(oldRoom);
		currentRoom_y--;
		rooms[currentRoom_x][currentRoom_y].render(newRoom);
		goingToNorth = SCREEN_CHANGE_RATE;
	}
	
	public void goSouthRoom(Screen screen)
	{
		initChangeRoomScreens(screen);
		rooms[currentRoom_x][currentRoom_y].render(oldRoom);
		currentRoom_y++;
		rooms[currentRoom_x][currentRoom_y].render(newRoom);
		goingToSouth = SCREEN_CHANGE_RATE;
	}
	
	public void goEastRoom(Screen screen)
	{
		initChangeRoomScreens(screen);
		rooms[currentRoom_x][currentRoom_y].render(oldRoom);
		currentRoom_x++;
		rooms[currentRoom_x][currentRoom_y].render(newRoom);
		goingToEast = SCREEN_CHANGE_RATE;
	}
	
	public void goWestRoom(Screen screen)
	{
		initChangeRoomScreens(screen);
		rooms[currentRoom_x][currentRoom_y].render(oldRoom);
		currentRoom_x--;
		rooms[currentRoom_x][currentRoom_y].render(newRoom);
		goingToWest = SCREEN_CHANGE_RATE;
	}
	
	private void initChangeRoomScreens(Screen screen)
	{
		/*if(oldRoom == null)
		{
			oldRoom = new Screen(screen.width,screen.height);
			rooms[currentRoom_x][currentRoom_y].render(oldRoom);
		}
		else
			oldRoom = newRoom;*/
		
		oldRoom = new Screen(screen.width,screen.height);
		newRoom = new Screen(screen.width,screen.height);
	}

	public void testOutput() {
		for (int j=0; j<LEVEL_Y; j++) 
		{
			for(int i=0;i<LEVEL_X; i++) 
			{	
				if(rooms[i][j]==null)
					System.out.print("   ");
				else if(rooms[i][j].hasNorthDoor)
					System.out.print(" # ");
				else
					System.out.print("   ");
			}
			
			System.out.println("");
			
			for(int i=0;i<LEVEL_X; i++)
			{
				if(rooms[i][j]==null)
					System.out.print(" _ ");
				else
				{
					if(rooms[i][j].hasWestDoor)
						System.out.print("#");
					else
						System.out.print(" ");
								
					if(rooms[i][j].roomType == RoomType.NORMAL_ROOM)
						System.out.print("N");
					else if(rooms[i][j].roomType == RoomType.START_ROOM)
						System.out.print("S");
					else 
						System.out.print("?");

					if(rooms[i][j].hasEastDoor)
						System.out.print("#");
					else
						System.out.print(" ");
				}

			}
			
			System.out.println("");
			
			for(int i=0;i<LEVEL_X; i++)
			{	
				if(rooms[i][j]==null)
					System.out.print("   ");
				else if(rooms[i][j].hasSouthDoor)
					System.out.print(" # ");
				else
					System.out.print("   ");
			}
			
			System.out.println("");
		}
		
	}

	public void render(Screen screen) {

		
		if(goingToNorth>0)
		{
			screen.draw(oldRoom,0,(SCREEN_CHANGE_RATE-goingToNorth)*screen.height/SCREEN_CHANGE_RATE);
			screen.draw(newRoom,0,-goingToNorth*screen.height/SCREEN_CHANGE_RATE);
			goingToNorth--;
		}
		else if(goingToSouth>0)
		{
			screen.draw(oldRoom,0,(goingToSouth-SCREEN_CHANGE_RATE)*screen.height/SCREEN_CHANGE_RATE);
			screen.draw(newRoom,0,goingToSouth*screen.height/SCREEN_CHANGE_RATE);
			goingToSouth--;
		}
		else if(goingToWest>0)
		{
			screen.draw(oldRoom,(SCREEN_CHANGE_RATE-goingToWest)*screen.width/SCREEN_CHANGE_RATE,0);
			screen.draw(newRoom,-goingToWest*screen.width/SCREEN_CHANGE_RATE,0);
			goingToWest--;
		}
		else if(goingToEast>0)
		{
			screen.draw(oldRoom,(goingToEast-SCREEN_CHANGE_RATE)*screen.width/SCREEN_CHANGE_RATE,0);
			screen.draw(newRoom,goingToEast*screen.width/SCREEN_CHANGE_RATE,0);
			goingToEast--;
		}
		else
		{
			rooms[currentRoom_x][currentRoom_y].render(screen);
		}
	}

	public void renderUi(Screen screen) {
		// TODO Auto-generated method stub
		screen.clearWithColor(0xff008000);
		
	}
/*
	public Coordinate findNorthRoom(Coordinate room)
	{
		if(hasNorthRoom(room))
			return room.getNorthCoordinate();
		else
			return null;

	}
	
	public Coordinate findSouthRoom(Coordinate room)
	{
		if(hasSouthRoom(room))
			return room.getSouthCoordinate();
		else
			return null;

	}
	
	public Coordinate findWestRoom(Coordinate room)
	{
		if(hasWestRoom(room))
			return room.getWestCoordinate();
		else
			return null;

	}
	
	public Coordinate findEastRoom(Coordinate room)
	{
		if(hasEastRoom(room))
			return room.getEastCoordinate();
		else
			return null;
	}*/
	
	
}
